/*
 * Copyright 2013 JROSE
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jrose.core.jdbc.persistence.executor;

import org.apache.commons.lang3.StringUtils;
import org.jrose.core.jdbc.DatabaseConnection;
import org.jrose.core.jdbc.entity.EntityDefinition;
import org.jrose.core.jdbc.persistence.annotation.RequireQuery;
import org.jrose.core.jdbc.persistence.annotation.SqlTemplate;
import org.jrose.core.jdbc.persistence.query.Sql;
import org.jrose.core.util.ExtendedMap;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import java.io.Serializable;

@SqlTemplate("SELECT COUNT(1) FROM ${TABLE} ${QUERY}")
@RequireQuery
public class CountSqlExecutor<E extends Serializable> extends AbstractSqlExecutor<E> {
    public CountSqlExecutor(DatabaseConnection databaseConnection, EntityDefinition<E> entityDefinition) {
        super(databaseConnection, entityDefinition);
    }

    private boolean skipLimit = false;

    public CountSqlExecutor<E> skipLimit(boolean skipLimit) {
        this.skipLimit = skipLimit;
        return this;
    }

    @Override
    protected Sql generateNamedParameterSQL(String templateSQL) {
        String candidateSQL = templateSQL;
        Sql sql = this.query.generateCountSQL(entityDefinition, skipLimit);
        candidateSQL = StringUtils.replace(candidateSQL, "${QUERY}", sql.getSqls().get(0));
        sql.setCandidateSQL(candidateSQL);
        return sql;
    }

    @Override
    protected ExtendedMap doExecute(Sql sql) {
        NamedParameterJdbcTemplate namedParameterJdbcTemplate = databaseConnection.getNamedParameterJdbcTemplate();
        MapSqlParameterSource parameterSource = new MapSqlParameterSource();
        parameterSource.addValues(sql.getNamedParameters());
        long count = namedParameterJdbcTemplate.queryForObject(sql.getCandidateSQL(), parameterSource, Long.class);
        return ExtendedMap.set("COUNT", count);
    }
}
